home *** CD-ROM | disk | FTP | other *** search
/ Aminet 48 / Aminet 48 (2002)(GTI - Schatztruhe)[!][Apr 2002].iso / Aminet / dev / mui / urltext.lha / Urltext / Sources / mcc / class.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-01-25  |  27.0 KB  |  824 lines

  1.  
  2. #include "class.h"
  3. #include <utility/pack.h>
  4. #include <datatypes/textclass.h>
  5. #include <dos/dostags.h>
  6. #include <libraries/gadtools.h>
  7. #include <graphics/rpattr.h>
  8.  
  9. /****************************************************************************/
  10.  
  11. struct data
  12. {
  13.     char                        url[256];
  14.     char                        text[256];
  15.     int                         tLen;
  16.     struct MUI_RenderInfo       *mri;
  17.     struct TextExtent           te;
  18.     Object                      *menu;
  19.     struct TextFont             *tf;
  20.     ULONG                       flags;
  21.     LONG                        mouseOutPen;
  22.     LONG                        mouseOverPen;
  23.     LONG                        visitedPen;
  24.     LONG                        textpen;
  25.     struct MUI_EventHandlerNode he;
  26. };
  27.  
  28. enum
  29. {
  30.     UTFLG_Show              = 1<<0,
  31.     UTFLG_MouseOver         = 1<<1,
  32.     UTFLG_Active            = 1<<2,
  33.     UTFLG_Visited           = 1<<3,
  34.     UTFLG_DoVisitedPen      = 1<<4,
  35.     UTFLG_Fallback          = 1<<5,
  36.     UTFLG_Underline         = 1<<6,
  37.     UTFLG_SetMax            = 1<<7,
  38.     UTFLG_DoOpenURL         = 1<<8,
  39.     UTFLG_UserDoVisitedPen  = 1<<9,
  40.     UTFLG_UserFallback      = 1<<10,
  41.     UTFLG_UserUnderline     = 1<<11,
  42.     UTFLG_UserSetMax        = 1<<12,
  43.     UTFLG_UserDoOpenURL     = 1<<13,
  44.     UTFLG_FreeMouseOutPen   = 1<<14,
  45.     UTFLG_FreeMouseOverPen  = 1<<15,
  46.     UTFLG_FreeVisitedPen    = 1<<16,
  47.     UTFLG_Input             = 1<<17,
  48.     UTFLG_Disabled          = 1<<18,
  49.     UTFLG_NoMenu            = 1<<19,
  50.     UTFLG_UseFont           = 1<<20,
  51.     UTFLG_CloseFont         = 1<<21,
  52.     UTFLG_InVirtualGroup    = 1<<22,
  53.     UTFLG_ActiveObject      = 1<<23,
  54. };
  55.  
  56. #define UTFLG_Use               (UTFLG_Active|UTFLG_Fallback)
  57. #define UTFLG_IsToShow(f)       (((ULONG)(f)) & UTFLG_Show)
  58. #define UTFLG_IsDisabled(f)     (((ULONG)(f)) & UTFLG_Disabled)
  59. #define UTFLG_IsToUse(f)        (((ULONG)(f)) & UTFLG_Use)
  60. #define UTFLG_IsMouseOver(f)    (((ULONG)(f)) & UTFLG_MouseOver)
  61. #define UTFLG_IsVisited(f)      ((((ULONG)(f)) & UTFLG_DoVisitedPen) && (((ULONG)(f)) & UTFLG_Visited))
  62. #define UTFLG_IsUnderline(f)    (((ULONG)(f)) & UTFLG_Underline)
  63. #define UTFLG_IsSetMax(f)       (((ULONG)(f)) & UTFLG_SetMax)
  64. #define UTFLG_IsDoOpenURL(f)    (((ULONG)(f)) & UTFLG_DoOpenURL)
  65.  
  66. /***********************************************************************/
  67.  
  68. struct urltextPackTags
  69. {
  70.     STRPTR  url;
  71.     STRPTR  text;
  72.     BOOL    doVisitedPen;
  73.     BOOL    fallBack;
  74.     BOOL    underline;
  75.     ULONG   flags;
  76. };
  77.  
  78. ULONG utTable[] =
  79. {
  80.     PACK_STARTTABLE(MUIA_Urltext_Base),
  81.  
  82.     PACK_ENTRY(MUIA_Urltext_Base,MUIA_Urltext_Url,urltextPackTags,url,PKCTRL_LONG|PKCTRL_PACKONLY),
  83.     PACK_ENTRY(MUIA_Urltext_Base,MUIA_Urltext_Text,urltextPackTags,text,PKCTRL_LONG|PKCTRL_PACKONLY),
  84.  
  85.     PACK_LONGBIT(MUIA_Urltext_Base,MUIA_Urltext_DoVisitedPen,urltextPackTags,flags,PKCTRL_BIT|PKCTRL_PACKONLY,UTFLG_DoVisitedPen),
  86.     PACK_LONGBIT(MUIA_Urltext_Base,MUIA_Urltext_FallBack,urltextPackTags,flags,PKCTRL_BIT|PKCTRL_PACKONLY,UTFLG_Fallback),
  87.     PACK_LONGBIT(MUIA_Urltext_Base,MUIA_Urltext_Underline,urltextPackTags,flags,PKCTRL_BIT|PKCTRL_PACKONLY,UTFLG_Underline),
  88.     PACK_LONGBIT(MUIA_Urltext_Base,MUIA_Urltext_SetMax,urltextPackTags,flags,PKCTRL_BIT|PKCTRL_PACKONLY,UTFLG_SetMax),
  89.     PACK_LONGBIT(MUIA_Urltext_Base,MUIA_Urltext_DoOpenURL,urltextPackTags,flags,PKCTRL_BIT|PKCTRL_PACKONLY,UTFLG_DoOpenURL),
  90.     PACK_LONGBIT(MUIA_Urltext_Base,MUIA_Urltext_NoMenu,urltextPackTags,flags,PKCTRL_BIT|PKCTRL_PACKONLY,UTFLG_NoMenu),
  91.  
  92.     PACK_LONGBIT(MUIA_Urltext_Base,MUIA_Urltext_DoVisitedPen,urltextPackTags,flags,PKCTRL_BIT|PKCTRL_PACKONLY|PSTF_EXISTS,UTFLG_UserDoVisitedPen),
  93.     PACK_LONGBIT(MUIA_Urltext_Base,MUIA_Urltext_FallBack,urltextPackTags,flags,PKCTRL_BIT|PKCTRL_PACKONLY|PSTF_EXISTS,UTFLG_UserFallback),
  94.     PACK_LONGBIT(MUIA_Urltext_Base,MUIA_Urltext_Underline,urltextPackTags,flags,PKCTRL_BIT|PKCTRL_PACKONLY|PSTF_EXISTS,UTFLG_UserUnderline),
  95.     PACK_LONGBIT(MUIA_Urltext_Base,MUIA_Urltext_SetMax,urltextPackTags,flags,PKCTRL_BIT|PKCTRL_PACKONLY|PSTF_EXISTS,UTFLG_UserSetMax),
  96.     PACK_LONGBIT(MUIA_Urltext_Base,MUIA_Urltext_DoOpenURL,urltextPackTags,flags,PKCTRL_BIT|PKCTRL_PACKONLY|PSTF_EXISTS,UTFLG_UserDoOpenURL),
  97.  
  98.     PACK_NEWOFFSET(MUIA_ContextMenu),
  99.     PACK_LONGBIT(MUIA_ContextMenu,MUIA_ContextMenu,urltextPackTags,flags,PKCTRL_BIT|PKCTRL_PACKONLY|PSTF_EXISTS,UTFLG_NoMenu),
  100.  
  101.     PACK_ENDTABLE
  102. };
  103.  
  104. static ULONG ASM
  105. mNew(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct opSet *msg)
  106. {
  107.     struct urltextPackTags  ut = {0};
  108.     register struct TagItem *attrs = msg->ops_AttrList,
  109.                             tags[] = {MUIA_InnerBottom,0,
  110.                                       MUIA_InnerLeft,0,
  111.                                       MUIA_InnerRight,0,
  112.                                       MUIA_InnerTop,0,
  113.                                       MUIA_Weight,0,
  114.                                       MUIA_InputMode,MUIV_InputMode_Immediate,
  115.                                       MUIA_ShowSelState,FALSE,
  116.                                       TAG_MORE,0};
  117.  
  118.     PackStructureTags(&ut,utTable,attrs);
  119.  
  120.     if (!ut.url) return 0;
  121.  
  122.     tags[7].ti_Data = (ULONG)attrs;
  123.     msg->ops_AttrList = tags;
  124.  
  125.     if (obj = (Object *)DoSuperMethodA(cl,obj,(APTR)msg))
  126.     {
  127.         register struct data    *data = INST_DATA(cl,obj);
  128.         register ULONG          flags = ut.flags;
  129.  
  130.         stccpy(data->url,ut.url,sizeof(data->url));
  131.  
  132.         stccpy(data->text,ut.text ? ut.text : ut.url,sizeof(data->text));
  133.         data->tLen = strlen(data->text);
  134.  
  135.         data->mri          = NULL;
  136.         data->mouseOutPen  = -1;
  137.         data->mouseOverPen = -1;
  138.         data->visitedPen   = -1;
  139.         data->textpen      = -1;
  140.         data->menu         = NULL;
  141.         data->tf           = NULL;
  142.  
  143.         if (!(flags & UTFLG_UserDoVisitedPen))
  144.             if (DEFAULT_DOVISITEDPEN) flags |= UTFLG_DoVisitedPen;
  145.             else flags &= ~UTFLG_DoVisitedPen;
  146.  
  147.         if (!(flags & UTFLG_UserFallback))
  148.             if (DEFAULT_FALLBACK) flags |= UTFLG_Fallback;
  149.             else flags &= ~UTFLG_Fallback;
  150.  
  151.         if (!(flags & UTFLG_UserUnderline))
  152.             if (DEFAULT_UNDERLINE) flags |= UTFLG_Underline;
  153.             else flags &= ~UTFLG_Underline;
  154.  
  155.         if (!(flags & UTFLG_UserSetMax))
  156.             if (DEFAULT_SETMAX) flags |= UTFLG_SetMax;
  157.             else flags &= ~UTFLG_SetMax;
  158.  
  159.         if (!(flags & UTFLG_UserDoOpenURL))
  160.             if (DEFAULT_SETMAX) flags |= UTFLG_DoOpenURL;
  161.             else flags &= ~UTFLG_DoOpenURL;
  162.  
  163.         if (OpenURLBase)
  164.         {
  165.             flags |= UTFLG_Active;
  166.             if (UTFLG_IsDoOpenURL(flags))
  167.                 DoMethod(obj,MUIM_Notify,MUIA_Pressed,1,obj,2,MUIM_Urltext_OpenURL,MUIV_Urltext_OpenURL_CheckOver);
  168.         }
  169.  
  170.         if (!(flags & UTFLG_NoMenu))
  171.         {
  172.             register Object *menu;
  173.             register BPTR   lock;
  174.  
  175.             if (lock = Lock("SYS:Prefs/OpenURL",SHARED_LOCK)) UnLock(lock);
  176.  
  177.             if (menu = MenustripObject,
  178.                 MUIA_Family_Child, MenuObjectT("Urltext"),
  179.                     MUIA_Family_Child, MenuitemObject,
  180.                         MUIA_Menuitem_Title, getString(Msg_Send),
  181.                         MUIA_Menuitem_Enabled, OpenURLBase,
  182.                         MUIA_UserData, Msg_Send,
  183.                     End,
  184.                     MUIA_Family_Child, MenuitemObject,
  185.                         MUIA_Menuitem_Title, getString(Msg_Copy),
  186.                         MUIA_UserData, Msg_Copy,
  187.                     End,
  188.                     MUIA_Family_Child, MenuitemObject,
  189.                         MUIA_Menuitem_Title, NM_BARLABEL,
  190.                     End,
  191.                     MUIA_Family_Child, MenuitemObject,
  192.                         MUIA_Menuitem_Title, getString(Msg_OpenURLPrefs),
  193.                         MUIA_Menuitem_Enabled, lock,
  194.                         MUIA_UserData, Msg_OpenURLPrefs,
  195.                     End,
  196.                 End,
  197.             End) set(obj,MUIA_ContextMenu,data->menu = menu);
  198.         }
  199.  
  200.         data->flags = flags;
  201.     }
  202.  
  203.     msg->ops_AttrList = attrs;
  204.  
  205.     return (ULONG)obj;
  206. }
  207.  
  208. /***********************************************************************/
  209.  
  210. static ASM ULONG
  211. mDispose(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  212. {
  213.     register struct data    *data = INST_DATA(cl,obj);
  214.     register Object         *menu = data->menu;
  215.     register ULONG          res;
  216.  
  217.     res = DoSuperMethodA(cl,obj,msg);
  218.  
  219.     if (menu) MUI_DisposeObject(menu);
  220.  
  221.     return res;
  222. }
  223.  
  224. /***********************************************************************/
  225.  
  226. static ASM ULONG
  227. mGet(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct opGet *msg)
  228. {
  229.     register struct data *data = INST_DATA(cl,obj);
  230.  
  231.     switch(msg->opg_AttrID)
  232.     {
  233.         case MUIA_Urltext_Url:      *msg->opg_Storage = (ULONG)data->url; return TRUE;
  234.         case MUIA_Urltext_Text:     *msg->opg_Storage = (ULONG)data->text; return TRUE;
  235.         case MUIA_Urltext_Active:   *msg->opg_Storage = (data->flags & UTFLG_Active) ? TRUE : FALSE; return TRUE;
  236.         case MUIA_Urltext_Visited:  *msg->opg_Storage = (data->flags & UTFLG_Visited) ? TRUE : FALSE; return TRUE;
  237.         case MUIA_Version:          *msg->opg_Storage = VERSION; return TRUE;
  238.         case MUIA_Revision:         *msg->opg_Storage = REVISION; return TRUE;
  239.         case MUIA_Urltext_Version:  *msg->opg_Storage = (ULONG)VERSTAG+7;
  240.         default: return DoSuperMethodA(cl,obj,(APTR)msg);
  241.     }
  242. }
  243.  
  244. /***********************************************************************/
  245.  
  246. #define BOOLSAME(a,b) (((BOOL)(a) && (BOOL)(b)) || ((!(BOOL)(a)) && (!(BOOL)(b))))
  247.  
  248. static ULONG ASM
  249. mSets(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct opSet *msg)
  250. {
  251.     register struct data    *data = INST_DATA(cl,obj);
  252.     register struct TagItem *tag;
  253.     struct TagItem          *tstate;
  254.     register ULONG          flags, redraw, notifyUrl, over;
  255.  
  256.     flags = data->flags;
  257.     redraw = notifyUrl = over = 0;
  258.  
  259.     for (tstate = msg->ops_AttrList; tag = NextTagItem(&tstate); )
  260.     {
  261.         register ULONG tidata = tag->ti_Data;
  262.  
  263.         switch (tag->ti_Tag)
  264.         {
  265.             case MUIA_Urltext_MouseOver:
  266.                 if (!UTFLG_IsToUse(flags) || BOOLSAME(tidata,UTFLG_IsMouseOver(flags)))
  267.                     tag->ti_Tag = TAG_IGNORE;
  268.                 else
  269.                 {
  270.                     if (tidata)
  271.                     {
  272.                         flags |= UTFLG_MouseOver;
  273.                         over = 1;
  274.                     }
  275.                     else flags &= ~UTFLG_MouseOver;
  276.                     redraw = notifyUrl = 1;
  277.                 }
  278.                 break;
  279.  
  280.             case MUIA_Urltext_Visited:
  281.                 if (BOOLSAME(tidata,flags & UTFLG_Visited))
  282.                     tag->ti_Tag = TAG_IGNORE;
  283.                 else
  284.                 {
  285.                     if (tidata) flags |= UTFLG_Visited;
  286.                     else flags &= ~UTFLG_Visited;
  287.                     redraw = 1;
  288.                 }
  289.                 break;
  290.  
  291.             case MUIA_Disabled:
  292.                 if (BOOLSAME(tidata,UTFLG_IsDisabled(flags)))
  293.                     tag->ti_Tag = TAG_IGNORE;
  294.                 else
  295.                 {
  296.                     if (tidata) flags |= UTFLG_Disabled;
  297.                     else flags &= ~UTFLG_Disabled;
  298.                     redraw = 1;
  299.                 }
  300.                 break;
  301.  
  302.             case MUIA_Urltext_MouseOutPen:
  303.                 if (data->mri)
  304.                 {
  305.                     register LONG pen;
  306.  
  307.                     if ((pen = MUI_ObtainPen(data->mri,(struct MUI_PenSpec *)tidata,0))!=-1)
  308.                     {
  309.                         if (data->flags & UTFLG_FreeMouseOutPen) MUI_ReleasePen(data->mri,data->mouseOutPen);
  310.                         data->mouseOutPen = pen;
  311.                         data->flags |= UTFLG_FreeMouseOutPen;
  312.                         redraw = 1;
  313.                     }
  314.                 }
  315.                 break;
  316.  
  317.             case MUIA_Urltext_MouseOverPen:
  318.                 if (data->mri)
  319.                 {
  320.                     register LONG pen;
  321.  
  322.                     if ((pen = MUI_ObtainPen(data->mri,(struct MUI_PenSpec *)tidata,0))!=-1)
  323.                     {
  324.                         if (data->flags & UTFLG_FreeMouseOverPen) MUI_ReleasePen(data->mri,data->mouseOverPen);
  325.                         data->mouseOverPen = pen;
  326.                         data->flags |= UTFLG_FreeMouseOverPen;
  327.                         redraw = 1;
  328.                     }
  329.                 }
  330.                 break;
  331.  
  332.             case MUIA_Urltext_VisitedPen:
  333.                 if (data->mri)
  334.                 {
  335.                     register LONG pen;
  336.  
  337.                     if ((pen = MUI_ObtainPen(data->mri,(struct MUI_PenSpec *)tidata,0))!=-1)
  338.                     {
  339.                         if (data->flags & UTFLG_FreeVisitedPen) MUI_ReleasePen(data->mri,data->visitedPen);
  340.                         data->flags |= UTFLG_FreeVisitedPen;
  341.                         data->visitedPen = pen;
  342.                         redraw = 1;
  343.                     }
  344.                 }
  345.                 break;
  346.  
  347.             case MUIA_Urltext_PUnderline:
  348.                 if (tidata) flags |= UTFLG_Underline;
  349.                 else flags &= ~UTFLG_Underline;
  350.                 redraw = 1;
  351.                 break;
  352.  
  353.             case MUIA_Urltext_PDoVisitedPen:
  354.                 if (tidata) flags |= UTFLG_DoVisitedPen;
  355.                 else flags &= ~UTFLG_DoVisitedPen;
  356.                 redraw = 1;
  357.                 break;
  358.  
  359.             case MUIA_Urltext_PFallBack:
  360.                 if (tidata) flags |= UTFLG_Fallback;
  361.                 else flags &= ~UTFLG_Fallback;
  362.                 redraw = 1;
  363.                 break;
  364.         }
  365.     }
  366.  
  367.     data->flags = flags;
  368.  
  369.     if (redraw)
  370.     {
  371.         MUI_Redraw(obj,MADF_DRAWOBJECT);
  372.         if (notifyUrl) SetSuperAttrs(cl,obj,MUIA_Urltext_Url,over ? data->url : NULL,TAG_DONE);
  373.     }
  374.  
  375.     return DoSuperMethodA(cl,obj,(APTR)msg);
  376. }
  377.  
  378.  
  379. /***********************************************************************/
  380.  
  381. static ASM ULONG
  382. mSetup(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_Setup *msg)
  383. {
  384.     register struct data        *data = INST_DATA(cl,obj);
  385.     register struct TextFont    *df;
  386.     Object                      *parent;
  387.     register ULONG              flags = data->flags, v;
  388.     ULONG                       p;
  389.  
  390.     if (!DoSuperMethodA(cl,obj,(APTR)msg)) return FALSE;
  391.  
  392.     data->mri          = msg->RenderInfo;
  393.     data->mouseOutPen  = _pens(obj)[DEFAULT_MOUSEOUT_PEN];
  394.     data->mouseOverPen = _pens(obj)[DEFAULT_MOUSEOVER_PEN];
  395.     data->visitedPen   = _pens(obj)[DEFAULT_VISITED_PEN];
  396.     data->textpen      = _pens(obj)[MPEN_TEXT];
  397.  
  398.     if (DoMethod(obj,MUIM_GetConfigItem,MUIA_Urltext_MouseOutPen,&p))
  399.         set(obj,MUIA_Urltext_MouseOutPen,p);
  400.  
  401.     if (DoMethod(obj,MUIM_GetConfigItem,MUIA_Urltext_MouseOverPen,&p))
  402.         set(obj,MUIA_Urltext_MouseOverPen,p);
  403.  
  404.     if (DoMethod(obj,MUIM_GetConfigItem,MUIA_Urltext_VisitedPen,&p))
  405.         set(obj,MUIA_Urltext_VisitedPen,p);
  406.  
  407.     if (!(flags & UTFLG_UserDoVisitedPen))
  408.     {
  409.         if (DoMethod(obj,MUIM_GetConfigItem,MUIA_Urltext_DoVisitedPen,&p)) v = *(ULONG *)p;
  410.         else v = DEFAULT_DOVISITEDPEN;
  411.  
  412.         if (v) data->flags |= UTFLG_DoVisitedPen;
  413.         else data->flags &= ~UTFLG_DoVisitedPen;
  414.     }
  415.  
  416.     if (!(flags & UTFLG_UserFallback))
  417.     {
  418.         if (DoMethod(obj,MUIM_GetConfigItem,MUIA_Urltext_FallBack,&p)) v = *(ULONG *)p;
  419.         else v = DEFAULT_FALLBACK;
  420.  
  421.         if (v) data->flags |= UTFLG_Fallback;
  422.         else data->flags &= ~UTFLG_Fallback;
  423.     }
  424.  
  425.     if (!(flags & UTFLG_UserUnderline))
  426.     {
  427.         if (DoMethod(obj,MUIM_GetConfigItem,MUIA_Urltext_Underline,&p)) v = *(ULONG *)p;
  428.         else v = DEFAULT_UNDERLINE;
  429.  
  430.         if (v) data->flags |= UTFLG_Underline;
  431.         else data->flags &= ~UTFLG_Underline;
  432.     }
  433.  
  434.     df = _font(obj);
  435.     if (DoMethod(obj,MUIM_GetConfigItem,MUIA_Urltext_Font,&p))
  436.     {
  437.         register char   buf[256], *t, *s;
  438.         struct TextAttr ta;
  439.         long            ys;
  440.  
  441.         strcpy(buf,(STRPTR)p);
  442.  
  443.         if (t = strchr(buf,'/'))
  444.         {
  445.             *t++ = 0;
  446.             if (!stcd_l(t,&ys) || ys<=0) ys = 8;
  447.         }
  448.         else ys = 8;
  449.  
  450.         for (s = NULL, t = buf; *t; t++) if (*t=='.') s = t;
  451.         if (!s || stricmp(++s,"font")) strcat(buf,".font");
  452.  
  453.         ta.ta_Name  = buf;
  454.         ta.ta_YSize = ys;
  455.         ta.ta_Style = 0;
  456.         ta.ta_Flags = 0;
  457.  
  458.         if (data->tf = OpenDiskFont(&ta)) data->flags |= UTFLG_CloseFont;
  459.         else data->tf = df;
  460.     }
  461.     else data->tf = df;
  462.  
  463.     if (UTFLG_IsToUse(data->flags))
  464.     {
  465.         data->he.ehn_Class  = cl;
  466.         data->he.ehn_Object = obj;
  467.         data->he.ehn_Events = IDCMP_MOUSEMOVE;
  468.  
  469.         DoMethod(_win(obj),MUIM_Window_AddEventHandler,&data->he);
  470.         data->flags |= UTFLG_Input;
  471.     }
  472.  
  473.     parent = obj;
  474.     v = FALSE;
  475.     while (1)
  476.     {
  477.         get(parent,MUIA_Parent,&parent);
  478.         if (!parent) break;
  479.  
  480.         if (get(parent,MUIA_Virtgroup_Top,&p))
  481.         {
  482.             v = TRUE;
  483.             break;
  484.         }
  485.     }
  486.     if (v) data->flags |= UTFLG_InVirtualGroup;
  487.  
  488.     return TRUE;
  489. }
  490.  
  491. /***********************************************************************/
  492.  
  493. static ASM ULONG
  494. mCleanup(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_Setup *msg)
  495. {
  496.     register struct data *data = INST_DATA(cl,obj);
  497.  
  498.     if (data->flags & UTFLG_Input) DoMethod(_win(obj),MUIM_Window_RemEventHandler,&data->he);
  499.     if (data->flags & UTFLG_CloseFont) CloseFont(data->tf);
  500.     if (data->flags & UTFLG_FreeMouseOutPen) MUI_ReleasePen(data->mri,data->mouseOutPen);
  501.     if (data->flags & UTFLG_FreeMouseOverPen) MUI_ReleasePen(data->mri,data->mouseOverPen);
  502.     if (data->flags & UTFLG_FreeVisitedPen) MUI_ReleasePen(data->mri,data->visitedPen);
  503.  
  504.     data->mri = NULL;
  505.     data->flags &= ~(UTFLG_Input | UTFLG_CloseFont | UTFLG_FreeMouseOutPen | UTFLG_FreeMouseOverPen | UTFLG_FreeVisitedPen);
  506.  
  507.     return DoSuperMethodA(cl,obj,(APTR)msg);
  508. }
  509.  
  510. /***********************************************************************/
  511.  
  512. static ASM ULONG
  513. mAskMinMax(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_AskMinMax *msg)
  514. {
  515.     register struct data    *data = INST_DATA(cl,obj);
  516.     struct RastPort         rp;
  517.     register WORD           w, h;
  518.  
  519.     DoSuperMethodA(cl,obj,(APTR)msg);
  520.  
  521.     InitRastPort(&rp);
  522.     SetFont(&rp,data->tf);
  523.     TextExtent(&rp,data->text,data->tLen,&data->te);
  524.  
  525.     w = data->te.te_Width;
  526.     h = data->te.te_Height;
  527.  
  528.     msg->MinMaxInfo->MinWidth  += w;
  529.     msg->MinMaxInfo->MinHeight += h;
  530.     msg->MinMaxInfo->DefWidth  += w;
  531.     msg->MinMaxInfo->DefHeight += h;
  532.  
  533.     if (UTFLG_IsSetMax(data->flags))
  534.     {
  535.         msg->MinMaxInfo->MaxWidth  += w;
  536.         msg->MinMaxInfo->MaxHeight += h;
  537.     }
  538.     else
  539.     {
  540.         msg->MinMaxInfo->MaxWidth  += MBQ_MUI_MAXMAX;
  541.         msg->MinMaxInfo->MaxHeight += MBQ_MUI_MAXMAX;
  542.     }
  543.  
  544.     return 0;
  545. }
  546.  
  547. /***********************************************************************/
  548.  
  549. static ASM ULONG
  550. mShow(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  551. {
  552.     register struct data    *data = INST_DATA(cl,obj);
  553.     register ULONG          res;
  554.  
  555.     if (res = DoSuperMethodA(cl,obj,msg)) data->flags |= UTFLG_Show;
  556.  
  557.     return res;
  558. }
  559.  
  560. /***********************************************************************/
  561.  
  562. static ASM ULONG
  563. mHide(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  564. {
  565.     register struct data *data = INST_DATA(cl,obj);
  566.  
  567.     data->flags &= ~UTFLG_Show;
  568.  
  569.     return DoSuperMethodA(cl,obj,msg);
  570. }
  571.  
  572. /***********************************************************************/
  573.  
  574. static ASM ULONG
  575. mDraw(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_Draw *msg)
  576. {
  577.     register struct data    *data = INST_DATA(cl,obj);
  578.     register ULONG          flags = data->flags;
  579.  
  580.     DoSuperMethodA(cl,obj,(APTR)msg);
  581.  
  582.     if (UTFLG_IsToShow(flags) && (msg->flags & MADF_DRAWOBJECT))
  583.     {
  584.         register struct RastPort    *rp = _rp(obj);
  585.         struct TextFont             *tf;
  586.         register SHORT              l = _mtop(obj)-data->te.te_Extent.MinY;
  587.  
  588.         SetAPen(rp,
  589.             (UTFLG_IsToUse(flags) && !UTFLG_IsDisabled(flags)) ?
  590.                 (UTFLG_IsMouseOver(flags) ?
  591.                     MUIPEN(data->mouseOverPen) :
  592.                     (UTFLG_IsVisited(flags) ?
  593.                         MUIPEN(data->visitedPen) :
  594.                         MUIPEN(data->mouseOutPen))) :
  595.                 data->textpen);
  596.  
  597.         GetRPAttrs(rp,RPTAG_Font,&tf,TAG_DONE);
  598.         SetRPAttrs(rp,RPTAG_Font,data->tf,TAG_DONE);
  599.  
  600.         Move(rp,_mleft(obj),l);
  601.         Text(rp,data->text,data->tLen);
  602.         SetRPAttrs(rp,RPTAG_Font,tf,TAG_DONE);
  603.  
  604.         if (UTFLG_IsUnderline(flags))
  605.         {
  606.             Move(rp,_mleft(obj),++l);
  607.             Draw(rp,_mleft(obj)+data->te.te_Extent.MaxX,l);
  608.         }
  609.     }
  610.  
  611.     return 0;
  612. }
  613.  
  614. /***********************************************************************/
  615.  
  616. #define _between(a,x,b)             ((x)>=(a) && (x)<=(b))
  617. #define _isinobject(obj,x,y)        (_between(_mleft(obj),(x),_mright(obj)) && _between(_mtop(obj),(y),_mbottom(obj)))
  618. #define _isinobjectr(obj,r,x,y)     (_between(_mleft(obj),(x),(r)) && _between(_mtop(obj),(y),_mbottom(obj)))
  619.  
  620. static ASM ULONG
  621. mHandleEvent(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_HandleEvent *msg)
  622. {
  623.     if (msg->imsg && msg->imsg->Class==IDCMP_MOUSEMOVE)
  624.     {
  625.         register struct data    *data = INST_DATA(cl,obj);
  626.         register ULONG          over;
  627.         register WORD           r, x = msg->imsg->MouseX, y = msg->imsg->MouseY;
  628.  
  629.         r = UTFLG_IsSetMax(data->flags) ? _mright(obj) : _mleft(obj)+data->te.te_Width;
  630.  
  631.         if ((over = _isinobjectr(obj,r,x,y)) && (data->flags & UTFLG_InVirtualGroup))
  632.         {
  633.             Object *p = obj;
  634.  
  635.             while (1)
  636.             {
  637.                 get(p,MUIA_Parent,&p);
  638.                 if (!p) break;
  639.  
  640.                 if (!_isinobject(p,x,y))
  641.                 {
  642.                     over = FALSE;
  643.                     break;
  644.                 }
  645.             }
  646.         }
  647.  
  648.         set(obj,MUIA_Urltext_MouseOver,over ? TRUE : FALSE);
  649.     }
  650.  
  651.     return 0;
  652. }
  653.  
  654. /***********************************************************************/
  655.  
  656. static ASM ULONG
  657. mOpenURL(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_Urltext_OpenURL *msg)
  658. {
  659.     register struct data    *data = INST_DATA(cl,obj);
  660.     register STRPTR         url = data->url;
  661.     register ULONG          flags = data->flags, res = FALSE;
  662.  
  663.     if (url && *url && OpenURLBase && !UTFLG_IsDisabled(flags) &&
  664.         ((msg->flags & MUIV_Urltext_OpenURL_CheckOver) ? (data->flags & (UTFLG_MouseOver|UTFLG_ActiveObject)) : 1))
  665.     {
  666.         if (URL_Open(url,URL_NewWindow,TRUE,TAG_DONE))
  667.             set(obj,MUIA_Urltext_Visited,res = TRUE);
  668.     }
  669.  
  670.     return res;
  671. }
  672.  
  673. /***********************************************************************/
  674.  
  675. static ASM ULONG
  676. mCopy(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_Urltext_Copy *msg)
  677. {
  678.     register struct data        *data = INST_DATA(cl,obj);
  679.     register struct IFFHandle   *iff;
  680.     register STRPTR             url = data->url;
  681.     register ULONG              unit = msg->unit, res = 0, len;
  682.  
  683.     if (iff = AllocIFF())
  684.     {
  685.         if (iff->iff_Stream = (LONG)OpenClipboard(unit))
  686.         {
  687.             InitIFFasClip(iff);
  688.  
  689.             if (!OpenIFF(iff,IFFF_WRITE))
  690.             {
  691.                 res = !PushChunk(iff,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN) &&
  692.                       !PushChunk(iff,ID_FTXT,ID_CHRS,len = strlen(url)) &&
  693.                       (WriteChunkBytes(iff,url,len)>=0) &&
  694.                       !PopChunk(iff);
  695.  
  696.                 CloseIFF(iff);
  697.             }
  698.  
  699.             CloseClipboard((struct ClipboardHandle *)iff->iff_Stream);
  700.         }
  701.  
  702.         FreeIFF(iff);
  703.     }
  704.  
  705.     return res;
  706. }
  707.  
  708. /***********************************************************************/
  709.  
  710. static ASM ULONG
  711. mOpenURLPrefs(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  712. {
  713.     register BPTR in, out;
  714.  
  715.     if ((in  = Open("NIL:",MODE_OLDFILE)) &&
  716.         (out = Open("NIL:",MODE_OLDFILE)))
  717.     {
  718.         SystemTags("SYS:Prefs/OpenURL",
  719.                     SYS_Asynch, TRUE,
  720.                     SYS_Input, in,
  721.                     SYS_Output, out,
  722.                     NP_StackSize, 8192,
  723.                     TAG_DONE);
  724.         return TRUE;
  725.     }
  726.  
  727.     if (in) Close(in);
  728.  
  729.     return FALSE;
  730. }
  731.  
  732. /***********************************************************************/
  733.  
  734. static ULONG SAVEDS ASM
  735. mContextMenuChoice(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_ContextMenuChoice *msg)
  736. {
  737.     switch (muiUserData(msg->item))
  738.     {
  739.         case Msg_Send:
  740.             DoMethod(obj,MUIM_Urltext_OpenURL,0);
  741.             break;
  742.  
  743.         case Msg_Copy:
  744.             DoMethod(obj,MUIM_Urltext_Copy,0);
  745.             break;
  746.  
  747.         case Msg_OpenURLPrefs:
  748.             DoMethod(obj,MUIM_Urltext_OpenURLPrefs);
  749.             break;
  750.     }
  751.  
  752.     return 0;
  753. }
  754.  
  755. /***********************************************************************/
  756.  
  757. static ULONG SAVEDS ASM
  758. mActive(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  759. {
  760.     register struct data *data = INST_DATA(cl,obj);
  761.  
  762.     data->flags |= UTFLG_ActiveObject;
  763.  
  764.     return DoSuperMethodA(cl,obj,msg);
  765. }
  766.  
  767. /***********************************************************************/
  768.  
  769. static ULONG SAVEDS ASM
  770. mInactive(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  771. {
  772.     register struct data *data = INST_DATA(cl,obj);
  773.  
  774.     data->flags &= ~UTFLG_ActiveObject;
  775.  
  776.     return DoSuperMethodA(cl,obj,msg);
  777. }
  778.  
  779. /***********************************************************************/
  780.  
  781. static SAVEDS ASM ULONG
  782. dispatcher(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  783. {
  784.     switch(msg->MethodID)
  785.     {
  786.         case MUIM_HandleEvent:          return mHandleEvent(cl,obj,(APTR)msg);
  787.         case MUIM_Draw:                 return mDraw(cl,obj,(APTR)msg);
  788.         case OM_SET:                    return mSets(cl,obj,(APTR)msg);
  789.         case MUIM_Setup:                return mSetup(cl,obj,(APTR)msg);
  790.         case MUIM_Cleanup:              return mCleanup(cl,obj,(APTR)msg);
  791.         case MUIM_AskMinMax:            return mAskMinMax(cl,obj,(APTR)msg);
  792.         case MUIM_Show:                 return mShow(cl,obj,(APTR)msg);
  793.         case MUIM_Hide:                 return mHide(cl,obj,(APTR)msg);
  794.         case OM_NEW:                    return mNew(cl,obj,(APTR)msg);
  795.         case OM_DISPOSE:                return mDispose(cl,obj,(APTR)msg);
  796.         case OM_GET:                    return mGet(cl,obj,(APTR)msg);
  797.         case MUIM_ContextMenuChoice:    return mContextMenuChoice(cl,obj,(APTR)msg);
  798.         case MUIM_Urltext_OpenURL:      return mOpenURL(cl,obj,(APTR)msg);
  799.         case MUIM_Urltext_Copy:         return mCopy(cl,obj,(APTR)msg);
  800.         case MUIM_Urltext_OpenURLPrefs: return mOpenURLPrefs(cl,obj,(APTR)msg);
  801.         case MUIM_GoActive:             return mActive(cl,obj,(APTR)msg);
  802.         case MUIM_GoInactive:           return mInactive(cl,obj,(APTR)msg);
  803.         default:                        return DoSuperMethodA(cl,obj,msg);
  804.     }
  805. }
  806.  
  807. /***********************************************************************/
  808.  
  809. BOOL ASM
  810. initMCC(REG(a0) struct UrltextBase *base)
  811. {
  812.     if (base->mcc = MUI_CreateCustomClass((struct Library *)base,MUIC_Area,NULL,sizeof(struct data),dispatcher))
  813.     {
  814.         if (MUIMasterBase->lib_Version>=20)
  815.             base->mcc->mcc_Class->cl_ID = PRG;
  816.  
  817.         return TRUE;
  818.     }
  819.  
  820.     return FALSE;
  821. }
  822.  
  823. /***********************************************************************/
  824.